package cn.sh.library.gmwx.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import cn.sh.library.gmwx.bean.InstanceSearchBean;
import cn.sh.library.gmwx.bean.WorkSearchBean;
import cn.sh.library.gmwx.dto.Pager;
import cn.sh.library.gmwx.service.BookService;
import cn.sh.library.gmwx.service.RemoteService;
import cn.sh.library.gmwx.sparql.InstanceSparql;
import cn.sh.library.gmwx.sparql.ItemSparql;
import cn.sh.library.gmwx.sparql.WorkSparql;
import cn.sh.library.gmwx.utils.JSONUtils;

@Controller
@RequestMapping("/work")
public class WorkController extends BaseController {
    @Resource
    private BookService bookService;
    @Resource
    private WorkSparql workSparql;
    @Resource
    private InstanceSparql instanceSparql;
    @Resource
    private ItemSparql itemSparql;
    @Autowired
    private RemoteService remoteService;

    // 作品：全文检索 + 高级检索
    @ResponseBody
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public String search(WorkSearchBean search, Pager pager){
        Map<String, Object> result = new HashMap<>();
        List<Map<String, String>> list = this.bookService.list(search, pager);
        result.put("resultList", list);
        result.put("pager", pager);
        return JSONUtils.toJSon(result);
    }

    // 作品详情
    @ResponseBody
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public String view(String uri){
    	Map<String, Object> result = new HashMap<>();
        result.put("uri", uri);
        result.put("infos", this.workSparql.getWorkInfos(uri));
        result.put("coverHor", this.workSparql.getCoverHor(uri));
        return JSONUtils.toJSon(result);
    }

    // 通过 作品uri 获取书目
    @ResponseBody
    @RequestMapping(value = "/getInstances", method = RequestMethod.GET)
    public String getInstances(InstanceSearchBean search, String workUri, Pager pager){
        Map<String, Object> result = new HashMap<>();
        if (StringUtils.isNotBlank(workUri)) {
            search.setWork(workUri);
        }
        List<Map<String, String>> list = this.bookService.instances(search, pager);
        result.put("resultList", list);
        result.put("pager", pager);
        return JSONUtils.toJSon(result);
    }

    // 通过 书目uri 获取 Items
    @ResponseBody
    @RequestMapping(value = "/getItems", method = RequestMethod.GET)
    public String getItems(String instanceUri){
        Map<String, Object> result = new HashMap<>();
        List<Map<String, String>> list = this.itemSparql.getInstanceItems(instanceUri);
        result.put("resultList", list);
        return JSONUtils.toJSon(result);
    }

    // 通过"人名"，获取"人物详细信息" (连接"人名规范库"查询)
    @ResponseBody
    @RequestMapping(value = "/getRemotePersons", method = RequestMethod.GET)
    public String getRemotePersons(String person, Pager pager) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, String>> list = this.workSparql.getRemotePersons(person);
        result.put("resultList", list);
        return JSONUtils.toJSon(result);
    }

    // 获取作品RDF
    @ResponseBody
    @RequestMapping(value = "/rdf", method = RequestMethod.GET)
    public void rdf(HttpServletResponse response, String uri){
        ByteArrayOutputStream bos = (ByteArrayOutputStream) instanceSparql.instanceTempModel(uri);
        byte[] data = bos.toByteArray();
        String rdfData = new String(data, Charset.forName("utf-8"));
        response.setContentType("application/rdf+xml");
        try {
            response.getWriter().write(rdfData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 手动执行-预加载
    @ResponseBody
    @RequestMapping(value = "/updateFacet", method = RequestMethod.GET)
    public String updateFacet() {
        this.workSparql.updateFacetWork("bf:intendedAudience/bf:identifiedBy", "bf:IntendedAudience");
        this.workSparql.updateFacetWork("bf:genreForm/bf:identifiedBy", "bf:GenreForm");
        this.workSparql.updateFacetWork("bf:language/bf:identifiedBy", "bf:Language");
        this.workSparql.countWork();

        return "SUCCESS";
    }

    // 读者对象-分面
    @ResponseBody
    @RequestMapping(value = "/facetAudience", method = RequestMethod.GET)
    public String facetAudience(WorkSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.workSparql.countWorkFacet(search, "bf:intendedAudience/bf:identifiedBy"));
        return JSONUtils.toJSon(result);
    }

    // 文献类型-分面
    @ResponseBody
    @RequestMapping(value = "/facetGenre", method = RequestMethod.GET)
    public String facetGenre(WorkSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.workSparql.countWorkFacet(search, "bf:genreForm/bf:identifiedBy"));
        return JSONUtils.toJSon(result);
    }

    // 语种-分面
    @ResponseBody
    @RequestMapping(value = "/facetLanguage", method = RequestMethod.GET)
    public String facetLanguage(WorkSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.workSparql.countWorkFacet(search, "bf:language/bf:identifiedBy"));
        return JSONUtils.toJSon(result);
    }

    // 通过 作品uri, 获取-书目(instance)分面
    @ResponseBody
    @RequestMapping(value = "/facetInstanceAll", method = RequestMethod.GET)
    public String facetInstanceAll(InstanceSearchBean search, String workUri, String facet) {
        Map<String, Object> result = new HashMap<>();
        if (StringUtils.isNotBlank(workUri)) {
        	search.setWork(workUri);
        }
        result.put("type", this.instanceSparql.countInstanceFacet(search, facet));
        return JSONUtils.toJSon(result);
    }

    // 读者对象 + 文献类型 + 语种 - 分面
    @ResponseBody
    @RequestMapping(value = "/facetAll", method = RequestMethod.GET)
    public String facetAll(WorkSearchBean search){
        Map<String, Object> result = new HashMap<>();
        result.put("audience", this.workSparql.countWorkFacet(search, "bf:intendedAudience/bf:identifiedBy"));
        result.put("genre", this.workSparql.countWorkFacet(search, "bf:genreForm/bf:identifiedBy"));
        result.put("language", this.workSparql.countWorkFacet(search, "bf:language/bf:identifiedBy"));
        return JSONUtils.toJSon(result);
    }
}
